﻿using Dapper.Library;
using Encrypt.Library;
using MySql.Data.MySqlClient;
using Sql.DataBase;
using System;
using System.Data;

namespace Dapper.MySql.Library
{
    public static class MySqlDataBase
    {
        #region Connection

        /// <summary>
        /// 获取连接
        /// </summary>
        /// <returns>打开的链接，如果失败返回的是null</returns>
        public static MySqlConnection GetConnection(DatabaseName database)
        {
            //链接字符串，从工具中读取配置
            string connectionString = string.Empty;
            MySqlConnection connection = null;
            try
            {
                DatabaseInstance instance = DatabaseManager.GetDatabase(database.ToString());
                connectionString = bool.Parse(instance.IsEncryption) ? AESEncryptHelper.Decrypt(instance.ConnectionString) : instance.ConnectionString;

                if (string.IsNullOrEmpty(connectionString)) return null;

                connection = new MySqlConnection(connectionString);
                connection.Open();
                return connection;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 关闭数据库连接
        /// </summary>
        /// <param name="connection">数据库连接</param>
        private static void CloseConnection(MySqlConnection connection)
        {
            try
            {
                if (connection != null && connection.State == ConnectionState.Open)
                {
                    connection.Close();
                    connection.Dispose();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 查询命令
        /// <summary>
        /// 非事物查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sqlConnection"></param>
        /// <returns></returns>
        public static QuerySet<T> QuerySet<T>(this MySqlConnection sqlConnection)
        {
            try
            {
                return new QuerySet<T>(sqlConnection, new MySqlProvider());
            }
            catch (Exception ex)
            {
                CloseConnection(sqlConnection);
                throw ex;
            }
        }

        /// <summary>
        /// 事物查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sqlConnection"></param>
        /// <param name="dbTransaction"></param>
        /// <returns></returns>
        public static QuerySet<T> QuerySet<T>(this MySqlConnection sqlConnection, IDbTransaction dbTransaction)
        {
            try
            {
                return new QuerySet<T>(sqlConnection, new MySqlProvider(), dbTransaction);
            }
            catch (Exception ex)
            {
                CloseConnection(sqlConnection);
                throw ex;
            }
        }

        /// <summary>
        /// 非事物查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sqlConnection"></param>
        /// <returns></returns>
        public static QuerySql<T> QuerySql<T>(this MySqlConnection sqlConnection)
        {
            try
            {
                return new QuerySql<T>(sqlConnection, new MySqlProvider());
            }
            catch (Exception ex)
            {
                CloseConnection(sqlConnection);
                throw ex;
            }
        }

        /// <summary>
        /// 事物查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sqlConnection"></param>
        /// <param name="dbTransaction"></param>
        /// <returns></returns>
        public static QuerySql<T> QuerySql<T>(this MySqlConnection sqlConnection, IDbTransaction dbTransaction)
        {
            try
            {
                return new QuerySql<T>(sqlConnection, new MySqlProvider(), dbTransaction);
            }
            catch (Exception ex)
            {
                CloseConnection(sqlConnection);
                throw ex;
            }
        }

        #endregion

        #region 执行命令

        /// <summary>
        /// 非事物执行
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sqlConnection"></param>
        /// <returns></returns>
        public static CommandSet<T> CommandSet<T>(this MySqlConnection sqlConnection)
        {
            try
            {
                return new CommandSet<T>(sqlConnection, new MySqlProvider());
            }
            catch (Exception ex)
            {
                CloseConnection(sqlConnection);
                throw ex;
            }
        }


        /// <summary>
        /// 非事物执行
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sqlConnection"></param>
        /// <returns></returns>
        public static CommandSql<T> CommandSql<T>(this MySqlConnection sqlConnection)
        {
            try
            {
                return new CommandSql<T>(sqlConnection, new MySqlProvider());
            }
            catch (Exception ex)
            {
                CloseConnection(sqlConnection);
                throw ex;
            }
        }

        /// <summary>
        /// 事物执行
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sqlConnection"></param>
        /// <param name="dbTransaction"></param>
        /// <returns></returns>
        public static CommandSet<T> CommandSet<T>(this MySqlConnection sqlConnection, IDbTransaction dbTransaction)
        {
            try
            {
                return new CommandSet<T>(sqlConnection, new MySqlProvider(), dbTransaction);
            }
            catch (Exception ex)
            {
                CloseConnection(sqlConnection);
                throw ex;
            }
        }

        /// <summary>
        /// 事物执行
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sqlConnection"></param>
        /// <param name="dbTransaction"></param>
        /// <returns></returns>
        public static CommandSql<T> CommandSql<T>(this MySqlConnection sqlConnection, IDbTransaction dbTransaction)
        {
            try
            {
                return new CommandSql<T>(sqlConnection, new MySqlProvider(), dbTransaction);
            }
            catch (Exception ex)
            {
                CloseConnection(sqlConnection);
                throw ex;
            }
        }

        /// <summary>
        /// 事物
        /// </summary>
        /// <param name="sqlConnection"></param>
        /// <param name="action"></param>
        /// <param name="exAction"></param>
        public static void Transaction(this MySqlConnection sqlConnection, Action<TransContext> action,
            Action<System.Exception> exAction = null)
        {
            if (sqlConnection.State == ConnectionState.Closed)
                sqlConnection.Open();

            var transaction = sqlConnection.BeginTransaction();
            try
            {
                action(new TransContext(sqlConnection, transaction, new MySqlProvider()));
                transaction.Commit();
            }
            catch (System.Exception ex)
            {
                if (exAction != null)
                    exAction(ex);
                else
                {
                    transaction.Rollback();
                }
                CloseConnection(sqlConnection);
            }
        }

        #endregion
    }
}
